import java.util.ArrayList;
import java.util.Arrays;

/**
 * @Author: 黄名富
 * @Description: 自定义List - 迭代器模式
 * @CreationDate: 2024/5/27
 */
public class CustomList<T> {

    public static void main(String[] args) {
        CustomList<Integer> list = new CustomList<>();
        for (int i = 0; i < 21; i++) list.addItem(i);
        Iterator<?> iterate = list.createIterate();
        while (iterate.hasNext()) System.out.println(iterate.next());
    }

    public Iterator<T> createIterate() {
        return new CustomIterator();
    }

    public interface Iterator<E> {
        E first();

        E next();

        boolean hasNext();

        E currentItem();
    }

    private class CustomIterator implements Iterator<T> {

        private int pos = 0;

        @SuppressWarnings("unchecked")
        @Override
        public T first() {
            if (currentPos <= 0) {
                throw new RuntimeException("访问超出界限");
            }
            return (T)items[0];
        }

        @SuppressWarnings("unchecked")
        @Override
        public T next() {
            if (hasNext()) {
                return (T)items[pos++];
            }
            return null;
        }

        @Override
        public boolean hasNext() {
            return pos < currentPos;
        }

        @SuppressWarnings("unchecked")
        @Override
        public T currentItem() {
            if (pos == 0) return first();
            return (T)items[pos-1];
        }
    }

    private static final int INIT_LENGTH = 20;

    Object[] items;

    private int currentPos = 0;

    public CustomList() {
        this.items = new Object[INIT_LENGTH];
    }

    public void addItem(T item) {
        checkArrayLength();
        items[currentPos++] = item;
    }

    @SuppressWarnings("unchecked")
    public T getItem(int pos) {
        if (pos >= currentPos) {
            throw new RuntimeException("访问超出界限");
        }
        return (T)items[pos];
    }

    private void checkArrayLength() {
        if (currentPos == items.length) {
            items = Arrays.copyOf(items,items.length * 2);
        }
    }

}
